package com.duniptech.soa.modeling;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StringWriter;
import java.util.Set;

import javax.xml.bind.JAXB;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public abstract class AtomicBase implements AtomicInterface {
	protected String name;
	protected Ports input;
	protected Ports output;
	
	public AtomicBase(Element xmlAtomic) throws Exception {
		name = xmlAtomic.getAttribute("name");
		input = new Ports();
		output = new Ports();
		NodeList xmlChildren = xmlAtomic.getChildNodes();
		for(int i=0; i<xmlChildren.getLength(); ++i) {
			Node xmlChild = xmlChildren.item(i);
			if(xmlChild.getNodeType()==Node.ELEMENT_NODE) {
				if(xmlChild.getNodeName().equals("inport")) {
					Element xmlInport = (Element)xmlChild;	
					input.addPort(xmlInport.getAttribute("name"), xmlInport.getAttribute("class"));
				}
				else if(xmlChild.getNodeName().equals("outport")) {
					Element xmlOutport = (Element)xmlChild;
					output.addPort(xmlOutport.getAttribute("name"), xmlOutport.getAttribute("class"));
				}
			}
		}
	}
	
	public void addInPort(String portName, String portClass) {
		input.addPort(portName, portClass);
	}
	public void addOutPort(String portName, String portClass) {
		output.addPort(portName, portClass);
	}
	public Ports getInput() { return input; }
	public Ports getOutput() { return output; }
	
	public String[] getOutput(String portName) {
		Port port = output.get(portName);
		Set<Object> values = port.getValues();
		String[] xmlValues = new String[values.size()];
		int i = 0;
		for(Object value : values) {
			StringWriter writer = new StringWriter();  
			Result result = new StreamResult(writer);
			JAXB.marshal(value, result);
			String xmlValue = writer.toString();
			xmlValues[i++] = xmlValue;
		}
		return xmlValues;
	}
	
	public String getName() { return name; }
	
	public static AtomicBase fromByteArray(byte[] content) {
		AtomicBase object = null;
		ByteArrayInputStream i = new ByteArrayInputStream(content);
		try {
			ObjectInputStream in = new ObjectInputStream(i);
			object = (AtomicBase)in.readObject();
			in.close();
		}
		catch(Exception ee) {
			ee.printStackTrace();
		}
		return object;
	}

	public byte[] toByteArray() {
		ByteArrayOutputStream o = new ByteArrayOutputStream();
		try {
			ObjectOutputStream out = new ObjectOutputStream(o);
			out.writeObject(this);
			out.flush();
			out.close();
		}
		catch(Exception ee) {
			ee.printStackTrace();
		}
		return o.toByteArray();
	}


}
